﻿Imports System.Web.UI.DataVisualization.Charting
Imports System.Drawing
Public Class ChartCls
    Private chart1 As Chart

    Sub New(ByRef chartObj As Chart)
        chart1 = chartObj
    End Sub

    '设置图标的宽度和高度
    Sub setChartWidthAndHeight(ByVal iWidth As Single, ByVal iHeight As Single)
        chart1.Width = iWidth
        chart1.Height = iHeight
    End Sub

    '添加标题
    Function addTitle(ByVal titleText As String, Optional ByVal dockingPosition As Docking = Docking.Top, Optional ByVal alignType As ContentAlignment = ContentAlignment.TopCenter) As Title
        Dim title1 As Title = chart1.Titles.Add(titleText)
        title1.Docking = dockingPosition
        title1.Alignment = alignType

        Return title1
    End Function

    '设置标题字体
    Sub setTitleFont(ByRef titleFont As Font)
        For Each TitleObj As Title In chart1.Titles
            TitleObj.Font = titleFont
        Next
    End Sub
   
    '添加图表区域
    Sub addChartArea(ByVal chartAreaName As String)
        chart1.ChartAreas.Add(chartAreaName)
        chart1.ChartAreas(chartAreaName).AxisY.MajorGrid.LineColor = Color.FromArgb(231, 244, 245)
        chart1.ChartAreas(chartAreaName).AxisX.LabelStyle.Font = New System.Drawing.Font("宋体", 9)
        chart1.ChartAreas(chartAreaName).AxisX.TitleFont = New System.Drawing.Font("宋体", 9)
        chart1.ChartAreas(chartAreaName).AxisX2.LabelStyle.Font = New System.Drawing.Font("宋体", 9)
        chart1.ChartAreas(chartAreaName).AxisX2.TitleFont = New System.Drawing.Font("宋体", 9)
        chart1.ChartAreas(chartAreaName).AxisY.LabelStyle.Font = New System.Drawing.Font("宋体", 9)
        chart1.ChartAreas(chartAreaName).AxisY.TitleFont = New System.Drawing.Font("宋体", 9)
        chart1.ChartAreas(chartAreaName).AxisY2.LabelStyle.Font = New System.Drawing.Font("宋体", 9)
        chart1.ChartAreas(chartAreaName).AxisY2.TitleFont = New System.Drawing.Font("宋体", 9)

    End Sub

    '设置图表区域的位置
    Sub setChartAreaPosition(ByVal chartAreaName As String, Optional ByVal strPosition As String = "3,3,94,94")
        Dim positionArr() As String = strPosition.Split(",")
        chart1.ChartAreas(chartAreaName).Position.X = CType(positionArr(0), Single)
        chart1.ChartAreas(chartAreaName).Position.Y = CType(positionArr(1), Single)
        chart1.ChartAreas(chartAreaName).Position.Width = CType(positionArr(2), Single)
        chart1.ChartAreas(chartAreaName).Position.Height = CType(positionArr(3), Single)
    End Sub

    '设置是否启用3D效果
    Sub setEnabled3D(ByVal chartAreaName As String, Optional ByVal blEnabled As Boolean = True)
        chart1.ChartAreas(chartAreaName).Area3DStyle.Enable3D = blEnabled
    End Sub

    '设置轴标题
    Sub setAxisTitle(ByVal chartAreaName As String, ByVal AxisName As String, ByVal AxisTitle As String, Optional ByVal iTextOrientation As TextOrientation = TextOrientation.Auto, Optional ByVal iStringAlignment As StringAlignment = StringAlignment.Center)
        Dim axisObj As Axis = getAxis(chartAreaName, AxisName)

        If Not axisObj Is Nothing Then
            axisObj.Title = AxisTitle
            axisObj.TextOrientation = iTextOrientation
            axisObj.TitleAlignment = iStringAlignment
        End If
    End Sub

    '设置轴标题的颜色和字体
    Sub setAxisTitleFontAndColor(ByVal chartAreaName As String, ByVal AxisTitleFontObj As Font, ByVal iAxisTitleColor As Color, Optional ByVal isSetAll As Boolean = True, Optional ByVal AxisName As String = "Y")
        Dim axisObj As Axis

        If isSetAll Then
            axisObj = getAxis(chartAreaName, "X")

            If Not axisObj Is Nothing Then
                axisObj.TitleFont = AxisTitleFontObj
                axisObj.TitleForeColor = iAxisTitleColor
            End If

            axisObj = getAxis(chartAreaName, "X2")

            If Not axisObj Is Nothing Then
                axisObj.TitleFont = AxisTitleFontObj
                axisObj.TitleForeColor = iAxisTitleColor
            End If

            axisObj = getAxis(chartAreaName, "Y")

            If Not axisObj Is Nothing Then
                axisObj.TitleFont = AxisTitleFontObj
                axisObj.TitleForeColor = iAxisTitleColor
            End If

            axisObj = getAxis(chartAreaName, "Y2")

            If Not axisObj Is Nothing Then
                axisObj.TitleFont = AxisTitleFontObj
                axisObj.TitleForeColor = iAxisTitleColor
            End If
        Else
            axisObj = getAxis(chartAreaName, AxisName)

            If Not axisObj Is Nothing Then
                axisObj.TitleFont = AxisTitleFontObj
                axisObj.TitleForeColor = iAxisTitleColor
            End If
        End If
    End Sub

    '设置轴区间
    Sub setAxisInteral(ByVal chartAreaName As String, ByVal AxisName As String, Optional ByVal iInterval As Double = 1)
        Dim axisObj As Axis = getAxis(chartAreaName, AxisName)

        If Not axisObj Is Nothing Then
            axisObj.Interval = iInterval
        End If
    End Sub

    '设置坐标轴的 最小值、最大值、原点位置
    Sub setAxisforMinMaxCross(ByVal chartAreaName As String, ByVal AxisName As String, ByVal decMin As Decimal, ByVal decMax As Decimal, Optional ByVal decCrossing As Decimal = 0)
        Dim axisObj As Axis = getAxis(chartAreaName, AxisName)

        If Not axisObj Is Nothing Then
            axisObj.Minimum = decMin
            axisObj.Maximum = decMax
            axisObj.Crossing = decCrossing
        End If
    End Sub

    '获取坐标轴
    Function getAxis(ByVal chartAreaName As String, ByVal AxisName As String) As Axis
        Dim axisObj As Axis
        AxisName = AxisName.ToUpper
        Select Case AxisName
            Case "Y"
                If chart1.ChartAreas(chartAreaName).AxisY.Enabled <> AxisEnabled.False Then
                    axisObj = chart1.ChartAreas(chartAreaName).AxisY
                End If
                Exit Select
            Case "X"
                If chart1.ChartAreas(chartAreaName).AxisX.Enabled <> AxisEnabled.False Then
                    axisObj = chart1.ChartAreas(chartAreaName).AxisX
                End If
                Exit Select
            Case "Y2"
                If chart1.ChartAreas(chartAreaName).AxisY2.Enabled <> AxisEnabled.False Then
                    axisObj = chart1.ChartAreas(chartAreaName).AxisY2
                End If
                Exit Select
            Case "X2"
                If chart1.ChartAreas(chartAreaName).AxisX2.Enabled <> AxisEnabled.False Then
                    axisObj = chart1.ChartAreas(chartAreaName).AxisX2
                End If
                Exit Select
        End Select

        Return axisObj
    End Function


    '设置X轴的标签样式
    Sub setXAxisLableStyle(ByVal styleName As String, Optional ByVal iValue As Double = 30)
        If styleName.ToUpper = "ANGLE" Then
            chart1.ChartAreas(0).AxisX.LabelStyle.Angle = iValue
        ElseIf styleName.ToUpper = "ISSTAGGERED" Then
            chart1.ChartAreas(0).AxisX.LabelStyle.IsStaggered = CBool(iValue)
        End If
    End Sub

    '添加图例
    Sub addChartLegend(ByVal legendName As String, Optional ByVal legendStyle As LegendStyle = LegendStyle.Table, Optional ByVal dockingPosition As Docking = Docking.Bottom, Optional ByVal alignType As StringAlignment = StringAlignment.Center)
        chart1.Legends.Add(legendName)
        setChartLegendStyle(legendName, legendStyle)
        setChartLegendPosition(legendName, dockingPosition, alignType)
        chart1.Legends(legendName).BackColor = Color.FromArgb(244, 244, 244)
        chart1.Legends(legendName).ShadowOffset = 2
        chart1.Legends(legendName).Font = New System.Drawing.Font("宋体", 9)
    End Sub

    '设置图例样式
    Sub setChartLegendStyle(ByVal legendName As String, Optional ByVal legendStyle As LegendStyle = LegendStyle.Table)
        '设置分类的展示
        chart1.Legends(legendName).LegendStyle = legendStyle
    End Sub

    Sub setChartLegendShadowAndBackColor(ByVal legendName As String, ByVal colorObj As Color, Optional ByVal iShadowOffset As Integer = 2)
        chart1.Legends(legendName).BackColor = colorObj
        chart1.Legends(legendName).ShadowOffset = iShadowOffset
    End Sub
    '设置图例位置
    Sub setChartLegendPosition(ByVal legendName As String, Optional ByVal dockingPosition As Docking = Docking.Bottom, Optional ByVal alignType As StringAlignment = StringAlignment.Center)
        '设置分类的位置（上、下、中、左、右）
        chart1.Legends(legendName).Docking = dockingPosition
        '设置分类的位置（上、中、下、左、中、右）
        chart1.Legends(legendName).Alignment = alignType
    End Sub

    '添加图表序列
    Sub addChartSerie(ByVal SerieName As String, ByVal serieChartType As SeriesChartType, ByVal chartAreaName As String, ByVal legendName As String)
        chart1.Series.Add(SerieName)
        chart1.Series(SerieName).ChartType = CType(serieChartType, SeriesChartType)
        chart1.Series(SerieName).ChartArea = chartAreaName
        chart1.Series(SerieName).Legend = legendName
    End Sub

    '设置序列是否显示第二坐标轴
    Sub setSerieTwoAxis(ByVal SerieName As String, ByVal axisName As String, ByVal IsEnableSecondAxis As Boolean)
        Select Case axisName
            Case "Y"
                If IsEnableSecondAxis Then
                    chart1.Series(SerieName).YAxisType = AxisType.Secondary
                Else
                    chart1.Series(SerieName).YAxisType = AxisType.Primary
                End If
                Exit Select
            Case "X"
                If IsEnableSecondAxis Then
                    chart1.Series(SerieName).XAxisType = AxisType.Secondary
                Else
                    chart1.Series(SerieName).XAxisType = AxisType.Primary
                End If
                Exit Select
        End Select
    End Sub

    '设置序列标记的 颜色、样式、大小
    Sub setSerieMarker(ByVal SerieName As String, ByVal axisName As String, ByVal iMarkerStyle As MarkerStyle, ByVal iColor As Color, ByVal iSize As Integer)
        chart1.Series(SerieName).MarkerStyle = iMarkerStyle
        chart1.Series(SerieName).MarkerColor = iColor
        chart1.Series(SerieName).MarkerSize = iSize
    End Sub

    '绑定数据
    Sub setSerieDataOrLabelAndTooltip(ByVal SerieName As String, ByRef datasource As System.Collections.IEnumerable, ByVal strXfield As String, ByVal strYfield As String, Optional ByVal strFieldAndFormatForLabel As String = "", Optional ByVal strFieldAndFormatForTooltip As String = "")
        Dim strDefined As String = ""
        If strFieldAndFormatForLabel = "" Then
            If strFieldAndFormatForTooltip <> "" Then
                strDefined = strFieldAndFormatForTooltip
            End If
        Else
            If strFieldAndFormatForTooltip = "" Then
                strDefined = strFieldAndFormatForLabel
            Else
                strDefined = strFieldAndFormatForLabel & "," & strFieldAndFormatForTooltip
            End If
        End If

        chart1.Series(SerieName).Points.DataBind(datasource, strXfield, strYfield, strDefined)

        If chart1.Series(SerieName).ChartType = SeriesChartType.Spline AndAlso chart1.Series(SerieName).Points.Count > 0 Then
            chart1.Series(SerieName).Points(0).MarkerStyle = MarkerStyle.Circle
            chart1.Series(SerieName).Points(0).MarkerSize = 4
        End If
    End Sub

    '设置序列的标签
    Sub setSerieLabel(ByVal SerieName As String, _
                      ByRef datasource As System.Collections.IEnumerable, _
                      Optional ByVal strFormatForLabel As String = "", _
                      Optional ByVal strFieldForLabel As String = "", _
                      Optional ByVal strFieldFormatForLabel As String = "")
        If strFormatForLabel <> "" Then

            If strFieldForLabel = "" Then
                chart1.Series(SerieName).Label = strFormatForLabel
            Else
                Dim iIndex As Integer = 0
                Dim arrField() As String = strFieldForLabel.Split("!")
                Dim i As Integer = 0
                Dim iFieldCnt As Integer = arrField.Length - 1
                Dim arrFieldFormat() As String = strFieldFormatForLabel.Split("!")
                Dim paramArr(iFieldCnt) As Object
                For Each da As DataPoint In chart1.Series(SerieName).Points
                    For i = 0 To iFieldCnt
                        If arrFieldFormat.Length >= i + 1 Then
                            If arrFieldFormat(i) = "" Then
                                paramArr(i) = datasource(iIndex).Item(arrField(i)).ToString()
                            Else
                                paramArr(i) = Format(datasource(iIndex).Item(arrField(i)), arrFieldFormat(i))
                            End If
                        Else
                            paramArr(i) = datasource(iIndex).Item(arrField(i)).ToString()
                        End If
                    Next
                    iIndex = iIndex + 1
                    '设置每个点的提示信息
                    da.Label = String.Format(strFormatForLabel, paramArr)
                Next
            End If
        End If
    End Sub

    '设置序列的提示
    Sub setSerieTooltip(ByVal SerieName As String, _
                        ByRef datasource As System.Collections.IEnumerable, _
                        Optional ByVal strFormatForTooltip As String = "", _
                        Optional ByVal strFieldForTooltip As String = "", _
                        Optional ByVal strFieldFormatForTooltip As String = "")
        If strFormatForTooltip <> "" Then

            If strFieldForTooltip = "" Then
                chart1.Series(SerieName).ToolTip = strFormatForTooltip
            Else
                Dim iIndex As Integer = 0
                Dim arrField() As String = strFieldForTooltip.Split("!")
                Dim i As Integer = 0
                Dim iFieldCnt As Integer = arrField.Length - 1
                Dim arrFieldFormat() As String = strFieldFormatForTooltip.Split("!")
                Dim paramArr(iFieldCnt) As Object
                For Each da As DataPoint In chart1.Series(SerieName).Points
                    For i = 0 To iFieldCnt
                        If arrFieldFormat.Length >= i + 1 Then
                            If arrFieldFormat(i) = "" Then
                                paramArr(i) = datasource(iIndex).Item(arrField(i)).ToString()
                            Else
                                paramArr(i) = Format(datasource(iIndex).Item(arrField(i)), arrFieldFormat(i))
                            End If
                        Else
                            paramArr(i) = datasource(iIndex).Item(arrField(i)).ToString()
                        End If
                    Next
                    iIndex = iIndex + 1

                    '设置每个点的提示信息
                    da.ToolTip = String.Format(strFormatForTooltip, paramArr)
                Next
            End If
        End If
    End Sub

    '设置序列的自定义属性（HTML）
    Sub setSerieMapAreaAttributes(ByVal SerieName As String, ByVal strMapAreaAttributes As String)
        chart1.Series(SerieName).MapAreaAttributes = strMapAreaAttributes
    End Sub

    '设置数据点的自定义属性（HTML）
    'dataSource---------------------------数据源,用来填充下面参数的alert({0})中的{0}
    'strFormatForMapAreaAttributes--------自定义属性的内容格式如：alert({0})
    'strFieldForMapAreaAttributes---------dataSource中用来填充alert({0})中的{0}的字段名称(用!分割)
    'strFieldFormatForMapAreaAttributes---用来格式化数据源中的数据的格式化字符串(用!分割)
    'iDataPointIndex----------------------用来指定设置哪个数据点的自定义属性
    'isSetAll-----------------------------是否设置所有的数据点的自定义属性
    Sub setSerieDataPointMapAreaAttributes(ByVal SerieName As String, _
                                           ByRef dataSource As System.Collections.IEnumerable, _
                                           ByVal strFormatForMapAreaAttributes As String, _
                                           Optional ByVal strFieldForMapAreaAttributes As String = "", _
                                           Optional ByVal strFieldFormatForMapAreaAttributes As String = "", _
                                           Optional ByVal iDataPointIndex As Integer = 0, _
                                           Optional ByVal isSetAll As Boolean = False)
        Dim iIndex As Integer = 0
        Dim arrField() As String = strFieldForMapAreaAttributes.Split("!")
        Dim i As Integer = 0
        Dim iFieldCnt As Integer = arrField.Length - 1
        Dim arrFieldFormat() As String = strFieldFormatForMapAreaAttributes.Split("!")
        Dim paramArr(iFieldCnt) As Object

        If isSetAll Then
            '循环每个数据点
            For Each da As DataPoint In chart1.Series(SerieName).Points
                '循环每个字段,格式化字段数据
                For i = 0 To iFieldCnt
                    If arrFieldFormat.Length >= i + 1 Then
                        If arrFieldFormat.Length >= i + 1 AndAlso arrFieldFormat(i) = "" Then
                            paramArr(i) = dataSource(iIndex).Item(arrField(i)).ToString()
                        Else
                            paramArr(i) = Format(dataSource(iIndex).Item(arrField(i)), arrFieldFormat(i))
                        End If
                    Else
                        paramArr(i) = dataSource(iIndex).Item(arrField(i)).ToString()
                    End If
                Next
                '设置数据点的自定义属性
                da.MapAreaAttributes = String.Format(strFormatForMapAreaAttributes, paramArr)
                iIndex = iIndex + 1
            Next
        Else
            For i = 0 To iFieldCnt
                If arrFieldFormat.Length >= i + 1 Then
                    If arrFieldFormat.Length >= i + 1 AndAlso arrFieldFormat(i) = "" Then
                        paramArr(i) = dataSource(0).Item(arrField(i)).ToString()
                    Else
                        paramArr(i) = Format(dataSource(iIndex).Item(arrField(i)), arrFieldFormat(i))
                    End If
                Else
                    paramArr(i) = dataSource(0).Item(arrField(i)).ToString()
                End If

            Next
            chart1.Series(SerieName).Points(iDataPointIndex).MapAreaAttributes = String.Format(strFormatForMapAreaAttributes, paramArr)
        End If
    End Sub

    '设置序列的自定义属性（MSChart）
    Sub setSerieCustomProperties(ByVal SerieName As String, ByVal strCustomProperties As String)
        chart1.Series(SerieName).CustomProperties = strCustomProperties
    End Sub

    '设置数据点的自定义属性（MSChart）
    Sub setSerieDataPointCustomProperties(ByVal SerieName As String, ByVal strCustomProperties As String, Optional ByVal iDataPointIndex As Integer = 0, Optional ByVal isSetAll As Boolean = False)
        If isSetAll Then
            For Each da As DataPoint In chart1.Series(SerieName).Points
                da.CustomProperties = strCustomProperties
            Next
        Else
            chart1.Series(SerieName).Points(iDataPointIndex).CustomProperties = strCustomProperties
        End If
    End Sub

    '判断序列是否存在
    Function SeriesIsExists(ByVal SerieName As String) As Boolean
        Dim blIsexist As Boolean = False
        Dim i, icnt As Integer
        icnt = chart1.Series.Count - 1
        For i = 0 To icnt
            If chart1.Series(i).Name = SerieName Then
                blIsexist = True
                Exit For
            End If
        Next
        Return blIsexist
    End Function

    '设置序列的标签是否显示
    Sub IsShowSerieLabel(ByVal SerieName As String, Optional ByVal blnShowLabel As Boolean = True)
        chart1.Series(SerieName).IsValueShownAsLabel = blnShowLabel
    End Sub

    '设置坐标轴标签的格式
    Sub setAxisLabelStyleFormat(ByVal chartAreaName As String, ByVal AxisName As String, ByVal strFormat As String)
        Dim axisObj As Axis = getAxis(chartAreaName, AxisName)

        If Not axisObj Is Nothing Then
            axisObj.LabelStyle.Format = strFormat
        End If
    End Sub

    '设置坐标轴的网格线是否显示
    Sub setChartAreaGridIsEnabled(ByVal chartAreaName As String, ByVal AxisName As String, ByVal strGridName As String, Optional ByVal blnEnabled As Boolean = True)
        Dim axisObj As Axis = getAxis(chartAreaName, AxisName)

        If Not axisObj Is Nothing Then
            If strGridName.ToUpper = "MAJORGRID" Then
                axisObj.MajorGrid.Enabled = blnEnabled
            Else
                axisObj.MinorGrid.Enabled = blnEnabled
            End If
        End If
    End Sub

    '隐藏坐标轴
    Sub hideChartAreaAxis(ByVal chartAreaName As String, ByVal AxisName As String)
        Dim axisObj As Axis = getAxis(chartAreaName, AxisName)

        If Not axisObj Is Nothing Then
            axisObj.LineColor = Color.White
        End If
    End Sub
End Class
